using System;
using System.Collections;
using TTXNA.src.Engine.Graphics;
using Microsoft.Xna.Framework;
using TTXNA.src.Util;
using TTXNA;
using Microsoft.Xna.Framework.Graphics;

namespace TTDotNet.Engine.ThreeDEngine
{
    public class TTScene
    {
        public ArrayList WorldObjects = new ArrayList();
        //public AJObject activeObject;
        //public AJObject.PickData activeObjectPD;
        public TTTerrain mainGrid;

        public void AddObject(TTObject newObject)
        {
            WorldObjects.Add(newObject);
        }

        public TTTerrain Terrain
        {
            get { return mainGrid; }
            set { mainGrid = value; }
        }
    
        public void RemoveObject(TTObject oldObject)
        {
            WorldObjects.Remove(oldObject);
        }

        public void ReloadResources()
        {
            mainGrid.ReloadResources();

            foreach (TTObject o in WorldObjects)
            {
                o.ReloadResources();
            }
        }

        public void Render(TTCamera camera)
        {
            //mainGrid.Render(camera);
            
            //TTXNAGame.graphics.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;

            //foreach (TTObject o in WorldObjects)
            //{
            //    o.Render(camera);
            //}
        }

        //public ObjectInstance Pick(TTCamera camera, Point mouseLoc, ObjectType type)
        //{
        //    Vector3 rayStart = GetRayStart(camera);
        //    Vector3 rayDirection = GetRayDirection(camera, mouseLoc);

        //    ObjectInstance nearestOfType = new ObjectInstance(null, Guid.Empty);
        //    IntersectInformation intInf;
        //    float minDistance = float.MaxValue;

        //    for (int i = 0; i < WorldObjects.Count; i++)
        //    {
        //        TTObject o = (TTObject)WorldObjects[i];

        //        if (o.ObjectType == type)
        //        {
        //            ObjectInstance instance = o.Pick(rayStart, rayDirection, camera, out intInf);

        //            if (instance.GUID != Guid.Empty && intInf.Dist < minDistance)
        //            {
        //                minDistance = intInf.Dist;
        //                nearestOfType = instance;
        //            }
        //        }
        //    }

        //    return nearestOfType;
        //}

        public GridPickData PickGrid(Point mouseLoc, TTCamera camera)
        {
            Vector3 rayStart = GetRayStart(camera);
            Vector3 rayDirection = GetRayDirection(camera, mouseLoc);

            return mainGrid.Pick(rayStart, rayDirection, camera);
        }

        private Vector3 GetRayDirection(TTCamera camera, Point point)
        {
            Vector3 v;
            v.X = (((2.0f * point.X) / TTXNAGame.graphics.GraphicsDevice.PresentationParameters.BackBufferWidth) - 1) / camera.Projection.M11;
            v.Y = -(((2.0f * point.Y) / TTXNAGame.graphics.GraphicsDevice.PresentationParameters.BackBufferHeight) - 1) / camera.Projection.M22;
            v.Z = 1.0f;

            Vector3 rayDirection = Vector3.Zero;

            Matrix m = camera.View;
            Matrix.Invert(ref m, out m);

            rayDirection.X = v.X * m.M11 + v.Y * m.M21 + v.Z * m.M31;
            rayDirection.Y = v.X * m.M12 + v.Y * m.M22 + v.Z * m.M32;
            rayDirection.Z = v.X * m.M13 + v.Y * m.M23 + v.Z * m.M33;

            return rayDirection;
        }

        private Vector3 GetRayStart(TTCamera camera)
        {
            Vector3 v;

            Matrix m = camera.View;
            Matrix.Invert(ref m, out m);

            v.X = m.M41;
            v.Y = m.M42;
            v.Z = m.M43;

            return v;
        }

    }

}
